package com.h2View.utils;

import com.h2View.exception.ServiceException;

import cn.hutool.core.io.FileUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xwx1052336
 * @since iFad Platform V100R001,2021/8/27
 */
public class MybatisConfigUtil {

    private Document doc;
    private Element rootEle;
    private Map<String,String> dbInfo = new HashMap<>(4);
    private String filePath;
    private static final String KEYCACHE = "MybatisConfigUtil";
    private Log log = LogFactory.get();

    public static void main(String[] args) {
        String path = " F:\\soft\\h2view\\classes\\artifacts\\h2view\\config\\mybatis-config.xml";
        MybatisConfigUtil.newInstance(path);
    }


    private MybatisConfigUtil(String path){
        MybatisConfigUtil mybatisConfigUtil = (MybatisConfigUtil) CacheUtil.get(path + KEYCACHE);
        if(mybatisConfigUtil != null){
            this.doc = mybatisConfigUtil.doc;
            rootEle = doc.getRootElement();
            return;
        }
        this.doc = getDocument(path);
        this.filePath = path;
        CacheUtil.put(path+KEYCACHE,this);
    }

    public static MybatisConfigUtil newInstance(String path) {
        return new MybatisConfigUtil(path);
    }

    public boolean save(){
        return save(filePath);
    }

    public String getFilePath(){
        return filePath;
    }

    public boolean save(String filePath){
        try(Writer writer = FileUtil.getWriter(filePath,"UTF-8",false)) {
            doc.write(writer);
            return true;
        } catch (IOException e) {
            log.error(e);
            return false;
        }

    }

    public void setDbInfo(Map<String,String> dbInfo){
        List<Element> propertyEles = rootEle.element("environments").element("environment").element("dataSource").elements("property");
        for(Element propertyEle:propertyEles){
            List<Attribute> attributes = new ArrayList<>(2);
            Attribute attributeValue = propertyEle.attribute("value");
            attributeValue.setValue(dbInfo.get(propertyEle.attributeValue("name")));
            attributes.add(propertyEle.attribute("name"));
            attributes.add(attributeValue);
            propertyEle.setAttributes(attributes);
        }
    }

    public Map<String,String> getDbInfo(boolean isRefrensh){
        if(isRefrensh||dbInfo.size()!=4){
            return getDbInfo();
        }else{
            return dbInfo;
        }
    }

    private Map<String,String> getDbInfo(){
        dbInfo.clear();
        List<Element> propertyEles = rootEle.element("environments").element("environment").element("dataSource").elements("property");
        for(Element propertyEle:propertyEles){
            dbInfo.put(propertyEle.attributeValue("name"),propertyEle.attributeValue("value"));
        }
        return dbInfo;
    }


    private  Document getDocument(String path){
        if(doc != null ){
            return doc;
        }
        SAXReader reader = new SAXReader();
        try {
            reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
            Document doc = reader.read(FileUtil.file(path));

            this.rootEle = doc.getRootElement();
            return doc;
        } catch (Exception e) {
            throw new ServiceException(path+"无法解析");
        }
    }

}
